$(document).ready(function() {
	var skiniko = new Skiniko().

	// Στο τοπικό σκηνικό εισάγουμε και property "zoom" στο οποίο θα κρατάμε
	// στοιχεία σχετικά με τα zoom DOM elements, π.χ. θέση, z-index κλπ.

	zoomReset().

	// Ενημερώνουμε άμεσα το σκηνικό με στοιχεία από το σκηνικό του skiser.
	// Τελευταίο βήμα στη διαδικασία ενημέρωσης τού σκηνικού είναι η πλήρης
	// ανανέωση του DOM με βάση τα στοιχεία τού σκηνικού.

	monitorAnaneosi();

	// Με το πλήκτρο της ανανέωσης αιτούμεθα εκ νέου σκηνικά δεδομένα από τον
	// skiser. Με την άφιξη των νέων στοιχείων ενημερώνεται πλήρως το σκηνικό
	// και το DOM, τόσο σε επίπεδο καταλόγων, όσο και σε επίπεδο zoom.

	$('#ananeosi').attr({
		title: 'Ανανέωση σκηνικών δεδομένων',
	}).on('click', function() {
		skiniko.monitorAnaneosi();
	});

	// Με το πλήκτρο απόκρυψης αποκρύπτουμε όλα τα zoomed elements, όσα δηλαδή
	// στοιχεία του σκηνικού αναπτύξαμε κάνοντας κλικ στα αντίστοιχα στοιχεία
	// καταλόγου.

	$('#apokripsi').attr({
		title: 'Απόκρυψη όλων των ανεπτυγμένων στοιχείων',
	}).on('click', function() {
		skiniko.monitorApokripsi();
	});

	// Το πλήκτρο της επαναφοράς επαναφέρει τα zoomed elements μετά την απόκρυψη
	// και μάλιστα στις ίδιες θέσεις που ίσως τα είχαμε μετακινήσει.

	$('#epanafora').attr({
		title: 'Επανεμφάνιση των ανεπτυγμένων στοιχείων',
	}).on('click', function() {
		skiniko.monitorEpanafora();
	});

	// Το πλήκτρο κλεισίματος διαγράφει όλα τα zoomed elements. Το πλήκτρο είναι
	// χρήσιμο όταν έχουμε ανοίξει πολλά zoom elements και είναι ασύμφορο να τα
	// κλείσουμε ένα ένα με το ειδικό πλήκτρο κλεισίματος που φέρουν όλα τα zoom
	// elements στην επάνω δεξιά τους γωνία. Με το κλείσιμο δεν παραγράφονται τα
	// στοιχεία θέσης των zoom elements, επομένως την επόμενη φορά που θα αναπτύξουμε
	// τα ίδια στοιχεία, τα zoom elements θα εμφανιστούν στις θέσεις στις οποίες τα
	// είχαμε τοποθετήσει.

	$('#klisimo').attr({
		title: 'Κλείσιμο και διαγραφή όλων των ανεπτυγμένων στοιχείων',
	}).on('click', function() {
		skiniko.monitorKlisimo();
	});

	// Το πλήκτρο καθαρισμού διαγράφει όλα τα zoomed elements παραγράφοντας όμως
	// και τα στοιχεία θέσης των συγκεκριμένων αντικειμένων.

	$('#katharismos').attr({
		title: 'Διαγραφή ανεπτυγμένων στοιχείων και των στοιχείων θέσης',
	}).on('click', function() {
		skiniko.monitorKatharismos();
	});

	// Το πλήκτρο εναλλαγής φέρνει στο προσκήνιο το παλαιότερο ανεπτυγμένο στοιχείο.
	// Αν η εναλλαγή γίνει μετά από απόκρυψη, ή ακόμη και μετά το κλείσιμο των zoomed
	// elements, τότε τα zoomed elements επανεμφανίζονται ως δια μαγείας.

	$('#enalagi').attr({
		title: 'Ανάδυση παλαιότερων ανεπτυγμένων στοιχείων',
	}).on('click', function() {
		skiniko.monitorEnalagi();
	});

	//Εναλλαγή μπορούμε να κάνουμε και σε επιλεγμένα στοιχεία, π.χ. μόνο σε παίκτες,
	// μόνο σε τραπέζια κλπ. Αυτό το επιτυγχάνουμε με κλικ στον τίτλο της σχετικής
	// στήλης στοιχείων καταλόγου.

	$('.titlos').on('mouseenter', function() {
		$(this).addClass('titlosOplisate');
	}).on('mouseleave', function() {
		$(this).removeClass('titlosOplisate');
	});

	$('#titlosSinedria').attr({
		title: 'Ανάδυση παλαιότερων ανεπτυγμένων στοιχείων συνεδριών',
	}).on('click', function() {
		skiniko.monitorEnalagi('sinedria');
	});

	$('#titlosPektis').attr({
		title: 'Ανάδυση παλαιότερων ανεπτυγμένων στοιχείων παικτών',
	}).on('click', function() {
		skiniko.monitorEnalagi('pektis');
	});

	$('#titlosTrapezi').attr({
		title: 'Ανάδυση παλαιότερων ανεπτυγμένων στοιχείων τραπεζιών',
	}).on('click', function() {
		skiniko.monitorEnalagi('trapezi');
	});
});

Skiniko.prototype.monitorAnaneosi = function() {
	var
	skiniko = this,
	ananeosi = $('#ananeosi');

	$('.provlima').remove();
	working(ananeosi);

	client.monitor(function(rsp) {
		working(ananeosi, false);

		console.log(rsp.responseText);
		if (rsp.sfalma) return globals.fatal(rsp.responseError);

		// Τα στοιχεία που αποστέλλονται από τον skiser είναι το ίδιο το σκηνικό σε
		// μορφή json. Επιχειρούμε, λοιπόν, άμεση ενημέρωση του τοπικού σκηνικού σε
		// επίπεδο στοιχείων (properties).

		try {
			eval('globals.initObject(skiniko, ' + rsp.responseText + ');');
		}

		// Αν έχουμε οποιοδήποτε πρόβλημα σε αυτό το σημείο σημαίνει ότι τα στοιχεία
		// που παραλάβαμε δεν είναι σε ορθό json format και κάνουμε διακοπή.

		catch(e) {
			return globals.fatal(e.message);
		}

		// Το σκηνικό έχει ενημερωθεί σε επίπεδο properties, αλλά πρέπει να μετατρέψουμε
		// τα επιμέρους στοιχεία σε αντικείμενα ώστε να μπορούμε να εφαρμόσουμε μεθόδους
		// στα αντικείμενα τού σκηνικού.

		skiniko.skiniko2object().

		// Ενημερώνουμε το DOM με τα σχτοιχεία καταλόγου του σκηνικού.

		monitor().

		// Επαναφέρουμε όσα zoomed elements υφίστανται και στο νέο instance του σκηνικού.

		zoomRestore();
	});

	return this;
}

Skiniko.prototype.monitorApokripsi = function() {
	var
	apokripsi = $('#apokripsi'),
	jql = $('.zoom');

	working(apokripsi);
	jql.fadeOut(100).promise().done(function() {
		working(apokripsi, false);
		jql.remove();
	});
	return this;
}

Skiniko.prototype.monitorEpanafora = function() {
	var epanafora = $('#epanafora');
	working(epanafora);
	working(epanafora, false);
	this.zoomRestore();
	return this;
}

Skiniko.prototype.monitorKlisimo = function() {
	var i, j,
	skiniko = this,
	klisimo = $('#klisimo'),
	jql = $('.zoom');

	working(klisimo);
	jql.fadeOut(100).promise().done(function() {
		working(klisimo, false);
		jql.remove();
	});

	for (i in skiniko.zoom) {
		for (j in skiniko.zoom[i]) {
			skiniko.zoom[i][j].klisto = true;
			delete skiniko.zoom[i][j].zidx;
		}
	}

	return this;
}

Skiniko.prototype.monitorKatharismos = function() {
	var
	katharismos = $('#katharismos'),
	jql = $('.zoom');

	working(katharismos);
	jql.fadeOut(100).promise().done(function() {
		working(katharismos, false);
		jql.remove();
	});

	return this.zoomReset();
}

Skiniko.prototype.monitorEnalagi = function(what) {
	var i, j,
	imin = null,
	zmin = null,
	enalagi = $('#enalagi');

	working(enalagi);
	working(enalagi, false);

	// Αν έχουμε καθορίσει ποιά από τα στοιχεία θέλουμε να προβάλλουμε, π.χ.
	// παίκτες, τραπέζια κλπ, τότε περιοριζόμαστε στα zoomed elemnts αυτού
	// του στοιχείου.

	if (what) {
		for (j in this.zoom[what]) {
			if (this.monitorEnalagiCheck(imin, zmin, what, j)) {
				imin = '#' + what + '\\:' + j;
				zmin = this.zoom[what][j].zidx;
			}
		}
	}

	// Δεν έχει καθοριστεί συγκεκριμένο είδος στοιχείων, επομένως εναλλάσσουμε
	// zoomed elements από όλα τα στοιχεία.

	else {
		for (i in this.zoom) {
			for (j in this.zoom[i]) {
				if (this.monitorEnalagiCheck(imin, zmin, i, j)) {
					imin = '#' + i + '\\:' + j;
					zmin = this.zoom[i][j].zidx;
				}
			}
		}
	}

	if (imin) $(imin).trigger('click');

	return this;
}

Skiniko.prototype.monitorEnalagiCheck = function(imin, zmin, what, idx) {
	if (!imin) return true;
	if (!this.zoom[what][idx].hasOwnProperty('zidx')) return true;
	if (!zmin) return false;
	return (this.zoom[what][idx].zidx < zmin);
}

function working(domel, nai) {
	if (nai === undefined) nai = true;
	if (nai) {
		domel.children('.workingIcon').remove();
		$('<img>').addClass('workingIcon').attr({
			src: '../ikona/working/default.gif',
		}).appendTo(domel);
	}
	else {
		domel.children('.workingIcon').fadeOut(function() {
			$(this).remove();
		});
	}
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////@

Skiniko.prototype.zoomReset = function() {
	this.zoom = {
		sinedria: {},
		pektis: {},
		trapezi: {},
	};

	return this;
}

Skiniko.prototype.zoomAdd = function(what, idx, zoomel, base) {
	var zoom = this.zoom;
	if (!zoom[what].hasOwnProperty(idx)) zoom[what][idx] = {
		top: '-10px',
		left: '-10px',
	};

	zoomel.css({display: 'inline'}).appendTo(base).css({
		top: zoom[what][idx].top,
		left: zoom[what][idx].left,
	}).siromeno({
		cursor: '',
		stop: function(e, ui) {
			ui.helper.removeClass('siromenoGrab').removeData('seKinisi');
			zoom[what][idx] = {
				top: ui.helper[0].offsetTop + 'px',
				left: ui.helper[0].offsetLeft + 'px',
				zidx: ui.helper[0].style.zIndex,
			};
		},
	}).klisimo(function(obj) {
		obj.parent().effect('highlight');
		obj.stop().effect('explode', 100, function() {
			$(this).remove();
			zoom[what][idx].klisto = true;
		});
	});

	if (zoom[what][idx].hasOwnProperty('zidx')) {
		zoomel.css({zIndex: zoom[what][idx].zidx});
		if (zoom[what][idx].zidx >= client.anadisiLevel) client.anadisiLevel = zoom[what][idx].zidx;
		delete zoom[what][idx].klisto;
	}
	else {
		this.zoomAnadisi(what, idx, zoomel);
	}

	return this;
}

Skiniko.prototype.zoomAnadisi = function(what, idx, zoomel, flash) {
	var zoom = this.zoom, fel = zoomel;
	zoomel.anadisi();
	if (flash) fel.add(fel.parent()).effect('highlight');
	zoom[what][idx].zidx = zoomel.css('zIndex');
	delete zoom[what][idx].klisto;
	return this;
}

Skiniko.prototype.zoomDelete = function(what, idx, zoomel) {
	var zoom = this.zoom;
	zoomel.remove();
	delete zoom[what][idx].zidx;
	return this;
}

Skiniko.prototype.zoomRestore = function(what) {
	var i, base, zoom = this.zoom;

	if (what === undefined) {
		this.zoomRestore('sinedria');
		this.zoomRestore('pektis');
		this.zoomRestore('trapezi');
		return this;
	}

	for (i in zoom[what]) {
		if (zoom[what][i].klisto) continue;
		base = $('#' + what + '\\:' + i);
		if (base.length) base.trigger('click');
		else delete zoom[what][i];
	}

	return this;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////@

Skiniko.prototype.monitor = function() {
	this.sinedriaMonitor();
	this.pektisMonitor();
	this.trapeziMonitor();
	return this;
}

Skiniko.prototype.sinedriaMonitor = function() {
	var 
	skiniko = this,
	col = $('#sinedria').empty();
	this.sinedriaWalk(function(pektis, sinedria) {
		col.append($('<div>').addClass('sinedria').attr({
			id: 'sinedria:' + pektis,
		}).text(pektis).
		on('click', function() {
			var
			sinedriaDOM = $(this),
			zoomDOM = $(this).find('.sinedriaZoom');

			if (zoomDOM.length) return skiniko.zoomAnadisi('sinedria', pektis, zoomDOM, true);

			zoomDOM = $('<div>').addClass('zoom sinedriaZoom');
			zoomDOM.append($('<div>').addClass('onomaZoom').text('login: ' + pektis));
			zoomDOM.append($('<div>').addClass('klidiZoom').text('klidi: ' + sinedria.klidi));
			zoomDOM.append($('<div>').addClass('ipZoom').text('ip: ' + sinedria.ip));
			zoomDOM.append($('<div>').addClass('isodosZoom').text('isodos: ' + sinedria.isodos));
			skiniko.zoomAdd('sinedria', pektis, zoomDOM, sinedriaDOM);
		}));
	});
	return this;
}

Skiniko.prototype.pektisMonitor = function() {
	var
	skiniko = this,
	col = $('#pektis').empty();

	this.pektisWalk(function(login, pektis) {
		var listaDom = $('<div>').addClass('pektis').attr({id: 'pektis:' + login,}).
			attr({title: login + '\n' + pektis.onoma + '\n' + pektis.email + '\n' + pektis.poll,});
		var elem = $('<ul>');
		var loginDom = $('<li>').html(login);
		var onomaDom = $('<li>').html(pektis.onoma);
		var emailDom = $('<li>').html(pektis.email);
		var pollDom = $('<li>').html(pektis.poll);

		elem.append(loginDom);
		//elem.append(onomaDom);
		//elem.append(emailDom);
		//elem.append(pollDom);
		listaDom.append(elem);
		col.append(listaDom);

		pektis.profinfoWalk(function(sxoliastis, profinfo) {
			var elem = $('<ol>');
			var sxoliastisDom = $('<li>').html(sxoliastis);
			var kimenoDom = $('<li>').html(profinfo.kimeno);

			elem.append(sxoliastisDom);
			elem.append(kimenoDom);
			listaDom.append(elem);
		}

		);
	});
	return this;
}

Skiniko.prototype.trapeziMonitor = function() {
	var
	skiniko = this,
	col = $('#trapezi').empty();

	this.trapeziWalk(function(kodikos, trapezi) {
		col.append($('<div>').addClass('trapezi').attr({
			id: 'trapezi:' + kodikos,
		}).text(kodikos + ': ' + trapezi.pektisGet(1) + ' vs ' +trapezi.pektisGet(2)).
		on('click', function() {
			var dataDOM, pektisDOM, i,
			trapeziDOM = $(this),
 			zoomDOM = $(this).find('.trapeziZoom');

			if (zoomDOM.length) return skiniko.zoomAnadisi('trapezi', kodikos, zoomDOM, true);

			zoomDOM = $('<div>').addClass('zoom trapeziZoom');

			dataDOM = $('<div>').addClass('kodikosZoom').append(kodikos);

			pektisDOM = $('<div>').html(trapezi.pektisGet(1));
			pektisDOM.addClass(trapezi.isApodoxi(1) ? 'apodoxi' : 'oxiApodoxi');
			pektisDOM.appendTo(dataDOM);

			dataDOM.append(' vs ');

			pektisDOM = $('<div>').html(trapezi.pektisGet(2));
			pektisDOM.addClass(trapezi.isApodoxi(2) ? 'apodoxi' : 'oxiApodoxi');
			pektisDOM.appendTo(dataDOM);

			dataDOM.appendTo(zoomDOM);

			trapezi.trparamWalk(function(kodikos, trparam) {
				trparam.trparamMonitor(zoomDOM);
			});

			trapezi.prosklisiWalk(function(kodikos, prosklisi) {
				prosklisi.prosklisiMonitor(zoomDOM);
			});

			trapezi.partidaWalk(function(i, partida) {
				partida.partidaMonitor(zoomDOM);
			});

			skiniko.zoomAdd('trapezi', kodikos, zoomDOM, trapeziDOM);
		}));
	});
	return this;
}

Profinfo.prototype.profinfoMonitor = function(parel) {
	$('<div>').addClass('profinfo').text(this.sxoliastisGet()).appendTo(parel);
}

Sxesi.prototype.sxesiMonitor = function(parel) {
	var sxesiDOM = $('<div>').addClass('sxesi').text(this.sxetizomenosGet()).appendTo(parel);
	if (this.isFilos()) sxesiDOM.addClass('filos');
	else if (this.isApoklismenos()) sxesiDOM.addClass('apoklismenos');
}

Trparam.prototype.trparamMonitor = function(parel) {
	$('<div>').addClass('trparam').
	append($('<div>').addClass('param').text(this.paramGet())).
	append(this.timiGet()).
	appendTo(parel);
}

Prosklisi.prototype.prosklisiMonitor = function(parel) {
	$('<div>').addClass('prosklisi').text(this.prosGet()).appendTo(parel);
}

Partida.prototype.partidaMonitor = function(parel) {
	var partidaDOM = $('<div>').addClass('partida').text(this.kodikosGet()).appendTo(parel);
	this.energiaWalk(function(i, energia) {
		energia.energiaMonitor(partidaDOM);
	});
}

Energia.prototype.energiaMonitor = function(parel) {
	$('<div>').addClass('energia energia' + this.pektisGet()).
	append(this.kodikos).
	append($('<div>').addClass('energiaIdos').text(this.idosGet())).
	appendTo(parel);
}

